package pagehelper

import (
	"math"
	"shop-common/utils"
	"shop-common/utils/queryWrapper"
)

type Paginator struct {
	Params *Params
	Record *Record
}

type Params struct {
	Current      int
	Size         int
	SelectFields []string
	WherePair    *queryWrapper.WherePair
	OrPair       []*queryWrapper.OrPair
	FullWhere    []*queryWrapper.WherePair
	OrderPair    []string
}

//binding
type Record struct {
	PrevPage int         `json:"prevPage"` // 上一页
	NextPage int         `json:"nextPage"` // 下一页
	Current  int         `json:"current"`  // 页码
	Size     int         `json:"size"`     // 每页条数
	Total    int64       `json:"total"`    // 总数据条数
	Pages    int         `json:"pages"`    // 总页数
	List     interface{} `json:"list"`     // 数据
}

func New() *Paginator {
	return &Paginator{
		Params: &Params{},
		Record: &Record{},
	}
}

func (r *Paginator) Push(wp *queryWrapper.WherePair) *Paginator {
	r.Params.FullWhere = append(r.Params.FullWhere, wp)
	return r
}

func (r *Paginator) IsPush(condition bool, wp *queryWrapper.WherePair) *Paginator {
	if condition {
		r.Params.FullWhere = append(r.Params.FullWhere, wp)
	}
	return r
}

func (r *Paginator) SetOrder(value string) *Paginator {
	if value == "" {
		return r
	}
	r.Params.OrderPair = append(r.Params.OrderPair, value)
	return r
}

func (r *Paginator) SetOffset(args interface{}) *Paginator {
	var pageRequest SearchPageRequest
	utils.StructMap(args, &pageRequest)
	r.Params.Current = pageRequest.Current
	r.Params.Size = pageRequest.Size
	return r
}

func (r *Paginator) Paginator() *Paginator {
	r.Replace(r.Params.Current, r.Params.Size)
	r.Params.WherePair = &queryWrapper.WherePair{}
	if len(r.Params.FullWhere) > 0 {
		for _, item := range r.Params.FullWhere {
			r.Params.WherePair = r.Params.WherePair.And(&queryWrapper.WherePair{Query: item.Query, Args: item.Args})
		}
	}
	return r
}

func (r *Paginator) Replace(current, size int) *Paginator {
	current, size = verifyParams(current, size)
	r.Params.Current = current
	r.Params.Size = size
	return r
}

func (r *Paginator) SetFilter(filters []string) *Paginator {
	r.Params.SelectFields = filters
	return r
}

func (r *Paginator) Count(count int64) *Paginator {
	if count == 0 {
		return r
	}
	r.Record.Current = r.Params.Current
	r.Record.Size = r.Params.Size
	r.Record.Pages = int(math.Ceil(float64(count) / float64(r.Params.Size)))
	r.Record.Total = count

	if r.Record.Current > 1 {
		r.Record.PrevPage = r.Record.Current - 1
	} else {
		r.Record.PrevPage = r.Record.Current
	}

	if r.Record.Current >= r.Record.Pages {
		r.Record.NextPage = r.Record.Current
	} else {
		r.Record.NextPage = r.Record.Current + 1
	}
	return r
}

/**
 * @param list 分页数据
 * @param count 总条数
 * @return
 * */
func (r *Paginator) Result(list interface{}, count int64) (*Record, error) {
	r.Record.List = list
	r.Record.Total = count
	return r.Count(count).Record, nil
}
